package org.ccay.registry.loader;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.ccay.core.log.CcayLoggerFactory;
import org.ccay.core.log.ILogger;
import org.ccay.core.registry.RegistryItem;
import org.ccay.core.util.DomUtil;
import org.ccay.core.util.StreamUtil;
import org.ccay.registry.exception.RegistryFileParseException;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;

/**
 * 从文件装载注册项配置
 * 装载classpath*:config/*registry.xml
 * @author chaowangbang
 * @since 2017年6月11日
 */
public class FileLoader implements IRegistryLoader {
	
	/** 日志记录器 **/
	private ILogger logger = CcayLoggerFactory
			.getLogger(FileLoader.class);

	@Override
	public Map<String,RegistryItem> load() {
		// 查找classpath上的*.registry.xml文件配置
		ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
		Map<String,RegistryItem> items = new HashMap<String,RegistryItem>();
		try {
			Resource[] resources = resourcePatternResolver.getResources("classpath*:config/*registry.xml");
			for (Resource resource : resources) {
				logger.debug("parseing Registry definition:" + resource.getFilename());
				items.putAll(parse(resource));
			}
		} catch (IOException e) {
			logger.error(e);
		}
		return items;
	}

	private Map<String, RegistryItem> parse(Resource resource) {
		Map<String,RegistryItem> items = new HashMap<String,RegistryItem>();
		InputStream in = null;
		try {
			in = resource.getInputStream();
			Document doc = DomUtil.loadDocument(new InputSource(in), null);
			Element elem = doc.getDocumentElement();
			if(elem!=null){
				List<Element> regElems = DomUtil.getChildElementsByTagName(elem,"reg");
				for (Iterator<Element> iter = regElems.iterator(); iter.hasNext();) {
					RegistryItem item = createRegistryItem(iter.next());
					items.put(item.getName(),item);
				}
			}
		} catch (IOException e) {
			// 创建流失败抛出异常
			logger.error("create InputStream failed", e);
			throw new RegistryFileParseException(resource.getFilename(), e);
		} finally {
			StreamUtil.closeStreams(in);
		}
		return items;
	}

	/**
	 * parse <reg name="CCC.CC" value="CCC.CCvalue" desc="哈哈哈" overwritable="false"/>
	 * @param next
	 * @return
	 */
	private RegistryItem createRegistryItem(Element elem) {
		RegistryItem item = new RegistryItem();
		item.setName(elem.getAttribute("name"));
		item.setValue(elem.getAttribute("value"));
		item.setDesc(elem.getAttribute("desc"));
		item.setOverwritable(Boolean.valueOf(elem.getAttribute("overwritable")));
		return item;
	}

}
